package com.test.uimremote.sim;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.BatteryManager;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
import android.telephony.CellInfo;
import android.telephony.CellLocation;
import android.telephony.TelephonyManager;
import android.telephony.cdma.CdmaCellLocation;
import android.telephony.gsm.GsmCellLocation;
import android.util.Log;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.util.List;

import static android.content.Context.BATTERY_SERVICE;

/**
 * TODO Add class comment here
 *
 * @author zhupeizhen
 * 2020/11/20
 */
public class SimAccessUtils {

    private static final String TAG = "SimAccessUtils";


    public static SimAccessAuthBean getSimAuthMsg(Context context) {

        SimAccessAuthBean bean = new SimAccessAuthBean();
        

        //        getRoot();

        TelephonyManager telManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        /** 获取SIM卡的IMSI码
         * SIM卡唯一标识：IMSI 国际移动用户识别码（IMSI：International Mobile Subscriber Identification Number）是区别移动用户的标志，
         * 储存在SIM卡中，可用于区别移动用户的有效信息。IMSI由MCC、MNC、MSIN组成，其中MCC为移动国家号码，由3位数字组成，
         * 唯一地识别移动客户所属的国家，我国为460；MNC为网络id，由2位数字组成，
         * 用于识别移动客户所归属的移动网络，中国移动为00，中国联通为01,中国电信为03；MSIN为移动客户识别码，采用等长11位数字构成。
         * 唯一地识别国内GSM移动通信网中移动客户。所以要区分是移动还是联通，只需取得SIM卡中的MNC字段即可
         * 电信的mnc 对应的是 sid）
         */
        // imei=    867956044501489
        // imsi=    460015964904513
        String imsi = telManager.getSubscriberId(); // 460015964904513
        if (imsi != null) {
            Log.d(TAG, "imsi=" + imsi);
            String MCC = imsi.substring(0, 3);
            String MNC = imsi.substring(3, 5);
            String MSIN = imsi.substring(5);
            Log.i(TAG, "MCC=" + MCC);
            if (imsi.startsWith("46000") || imsi.startsWith("46002")) {//因为移动网络编号46000下的IMSI已经用完，所以虚拟了一个46002编号，134/159号段使用了此编号
                //中国移动
                Log.i(TAG, "MNC=" + MNC + "=中国移动");
            } else if (imsi.startsWith("46001")) {
                //中国联通
                Log.i(TAG, "MNC=" + MNC + "=中国联通");
            } else if (imsi.startsWith("46003")) {
                //中国电信
                Log.i(TAG, "MNC=" + MNC + "=中国电信");
            } else {
                Log.i(TAG, "MNC=" + MNC + "");
            }
            Log.i(TAG, "MSIN=" + MSIN);
            
            bean.setMCC(Integer.valueOf(MCC));
            bean.setMNC(Integer.valueOf(MNC));
            
        } else {
            Log.i(TAG, "没有获取到sim卡信息");
        }

        int cellid = 0;
        int lac = 0;
//        int psc = 0;

        cellLocation(telManager);

        Log.d(TAG, "telManager.getPhoneType()=" + telManager.getPhoneType());

        // 位置权限！！！！！！！！！！！！！！！！！！
        List<CellInfo> allCellInfo = telManager.getAllCellInfo();
        if (allCellInfo != null) {
            for (CellInfo cellInfo : allCellInfo) {
                Log.d(TAG, "cellInfo=" + cellInfo);
            }
        } else {
            Log.d(TAG, "cellInfo=null");
        }

        CellLocation cel = telManager.getCellLocation();
        //移动联通 GsmCellLocation
        if (cel != null) {
            if (cel instanceof GsmCellLocation) {
                GsmCellLocation gsmCellLocation = (GsmCellLocation) cel;
                cellid = gsmCellLocation.getCid();
                lac = gsmCellLocation.getLac();
                //            psc = gsmCellLocation.getPsc();
            } else if (cel instanceof CdmaCellLocation) {
                //电信   CdmaCellLocation
                CdmaCellLocation cdmaCellLocation = (CdmaCellLocation) cel;
                cellid = cdmaCellLocation.getBaseStationId();
                lac = cdmaCellLocation.getNetworkId();
            }
            Log.i(TAG, "基站信息=" + cel.getClass().toString() + ",data=" + cel);
            Log.i(TAG, "cid基站id=" + cellid);
            Log.i(TAG, "lac位置区域码=" + lac);
            bean.setCID(cellid);
            bean.setLAC(lac);
        } else {
            Log.i(TAG, "没有获取到基站信息=" + cel);
        }

        BatteryManager batteryManager = (BatteryManager) context.getSystemService(BATTERY_SERVICE);
        int battery = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);
        Log.i(TAG, "电量=" + battery);
        bean.setBattery((byte) battery);

        // sn与imei
        String imeiOrSn = getImeiOrSn(context);
        bean.setSN(imeiOrSn);

        String appVersionName = getAppVersionName(context);
        Log.i(TAG, "版本名=" + appVersionName);
        bean.setVersionAPK(appVersionName);

        int releaseVer = -1;
        try {
            String tempReleaseVer = Build.VERSION.RELEASE;
            Log.i(TAG, "操作系统版本(FirmwareVer固件版本？)=" + tempReleaseVer);
            releaseVer = Integer.valueOf(tempReleaseVer);
        } catch (Exception e) {
            e.printStackTrace();
            Log.i(TAG, "操作系统版本(FirmwareVer固件版本？) 转换int失败");
        }
        bean.setFirmwareVer(releaseVer);

        String deviceSoftwareVersion = telManager.getDeviceSoftwareVersion();

        Log.d(TAG, "deviceSoftwareVersion=" + deviceSoftwareVersion);

        Log.d(TAG, "设备名称=" + android.os.Build.MODEL + ",品牌=" + android.os.Build.BRAND +
                ",SDK版本=" + android.os.Build.VERSION.SDK_INT);

        Log.d(TAG, "android.os.Build.FINGERPRINT=" + android.os.Build.FINGERPRINT);
        Log.d(TAG, "android.os.Build.BOARD=" + android.os.Build.BOARD);
        Log.d(TAG, "android.os.Build.HOST=" + Build.HOST);
        Log.d(TAG, "android.os.Build.ID=" + Build.ID);
        Log.d(TAG, "android.os.Build.SERIAL=" + Build.SERIAL);
        Log.d(TAG, "android.os.Build.VERSION.INCREMENTAL=" + Build.VERSION.INCREMENTAL);
        Log.d(TAG, "android.os.Build.DEVICE=" + Build.DEVICE);
        Log.d(TAG, "android.os.Build.DISPLAY=" + Build.DISPLAY);

        return bean;

    }

    private static void cellLocation(TelephonyManager mTelephonyManager) {
        // 返回值MCC + MNC （注意：电信的mnc 对应的是 sid）
        /*String operator = mTelephonyManager.getNetworkOperator();
        int mcc = -1;
        int mnc = -1;
        if(operator!=null&&operator.length()>3){
            mcc = Integer.parseInt(operator.substring(0, 3));
            mnc = Integer.parseInt(operator.substring(3));
        }

        // 获取邻区基站信息
        List<NeighboringCellInfo> infos = mTelephonyManager.getNeighboringCellInfo();
        StringBuffer sb = new StringBuffer("总数 : " + infos.size() + "\n");

        for (NeighboringCellInfo info1 : infos) { // 根据邻区总数进行循环
            sb.append(" LAC : " + info1.getLac()); // 取出当前邻区的LAC
            sb.append("\n CID : " + info1.getCid()); // 取出当前邻区的CID
            sb.append("\n BSSS : " + (-113 + 2 * info1.getRssi()) + "\n"); // 获取邻区基站信号强度
        }


        int type = mTelephonyManager.getNetworkType();

        Toast.makeText(this,"type:= "+type,Toast.LENGTH_LONG).show();
        //需要判断网络类型，因为获取数据的方法不一样
        if(type == TelephonyManager.NETWORK_TYPE_CDMA        // 电信cdma网
                || type == TelephonyManager.NETWORK_TYPE_1xRTT
                || type == TelephonyManager.NETWORK_TYPE_EVDO_0
                || type == TelephonyManager.NETWORK_TYPE_EVDO_A
                || type == TelephonyManager.NETWORK_TYPE_EVDO_B
                || type == TelephonyManager.NETWORK_TYPE_LTE){
            CdmaCellLocation cdma = (CdmaCellLocation) mTelephonyManager.getCellLocation();
            if(cdma!=null){
                sb.append(" MCC = " + mcc );
                sb.append("\n cdma.getBaseStationLatitude()"+cdma.getBaseStationLatitude()/14400 +"\n"
                        +"cdma.getBaseStationLongitude() "+cdma.getBaseStationLongitude()/14400 +"\n"
                        +"cdma.getBaseStationId()(cid)  "+cdma.getBaseStationId()
                        +"\n  cdma.getNetworkId()(lac)   "+cdma.getNetworkId()
                        +"\n  cdma.getSystemId()(mnc)   "+cdma.getSystemId());
            }else{
                sb.append("can not get the CdmaCellLocation");
            }

        }else if(type == TelephonyManager.NETWORK_TYPE_GPRS         // 移动和联通GSM网
                || type == TelephonyManager.NETWORK_TYPE_EDGE
                || type == TelephonyManager.NETWORK_TYPE_HSDPA
                || type == TelephonyManager.NETWORK_TYPE_UMTS
                || type == TelephonyManager.NETWORK_TYPE_LTE){
            GsmCellLocation gsm = (GsmCellLocation) mTelephonyManager.getCellLocation();
            if(gsm!=null){
                sb.append("  gsm.getCid()(cid)   "+gsm.getCid()+"  \n "//移动联通 cid
                        +"gsm.getLac()(lac) "+gsm.getLac()+"  \n "             //移动联通 lac
                        +"gsm.getPsc()  "+gsm.getPsc());
            }else{
                sb.append("can not get the GsmCellLocation");
            }
        }else if(type == TelephonyManager.NETWORK_TYPE_UNKNOWN){
            Toast.makeText(this,"电话卡不可用！",Toast.LENGTH_LONG).show();
        }

        Log.d(TAG,"mTelephonyManager.getNetworkType(); "+mTelephonyManager.getNetworkType());
        Log.d(TAG, " 获取邻区基站信息:" + sb.toString());*/
    }

    /**
     * input tap 10 20  代表点击屏幕x=10, y=20的坐标事件
     * input swipe 100 250 200 280 代表将屏幕x=100, y=250的坐标移动到x=200, y=280
     * input swipe 100 100 100 100 1000 这个可以代表长按事件，在屏幕x=100, y=100的地方长按屏幕 （长按事件有时会触发点击事件，可以返回 true 长按事件的时候取消点击事件）如下
     */
    private static void getRoot() {
        String cmd = "input tap 10 20";

        /*textView1.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                Log.d(TAG, "MainActivity textView1 OnLongClick");
                //返回 true 消费事件
                return true;
            }
        });*/

        // 申请获取root权限8.0出现流关闭异常，这一步很重要，不然会没有作用  将su 改成 /system/bin/sh
        try {
            // 申请超级用户权限
            Process process = Runtime.getRuntime().exec("su");
            // 不需要获取超级用户权限
//            Process process = Runtime.getRuntime().exec("/system/bin/sh");
            // 获取输出流
            OutputStream outputStream = process.getOutputStream();
            DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
            dataOutputStream.writeBytes(cmd);
            dataOutputStream.flush();
            dataOutputStream.close();
            outputStream.close();
            int code = process.waitFor();
            Log.d(TAG, "process.waitFor() = " + code);
        } catch (Throwable t) {
            Log.d(TAG, "Throwable = " + t.getMessage());
            t.printStackTrace();
        }
    }

    private static String getImeiOrSn(Context context) {
        String phoneIMEI = getPhoneIMEI(context);
        Log.i(TAG, "1...imei=" + phoneIMEI);

        String serial = Build.SERIAL;

        Log.d(TAG, "2...serial=" + serial);

        Handler mHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                Log.d(TAG, "3...SN: " + msg.obj.toString());
            }
        };
        Thread snThread = new Thread(new getSerialnoNumbers(mHandler));
        snThread.start();


        String[] propertys = {
                "ro.boot.serialno", "ro.serialno"
        };

        for (String key : propertys) {
            // String v = android.os.SystemProperties.get(key);
            String v = getAndroidOsSystemProperties(key);
            Log.d(TAG, "4...get " + key + " : " + v);
        }

        return phoneIMEI == null ? "" : phoneIMEI;
        
    }

    private static class getSerialnoNumbers implements Runnable {
        Handler mHandler;
        final String serialnoStr = "[ro.boot.serialno]";

        getSerialnoNumbers(Handler handler) {
            this.mHandler = handler;
        }

        public void run() {
            try {
                Process p = Runtime.getRuntime().exec("getprop");
                p.waitFor();
                BufferedReader stdInput = new BufferedReader(new InputStreamReader(
                        p.getInputStream()));
                String temp = "";
                while ((temp = stdInput.readLine()) != null) {
                    if (temp.contains(serialnoStr)) {
                        temp.replaceAll(" ", "");
                        int index = temp.indexOf(serialnoStr);
                        temp = temp.substring(index + 20);
                        temp = temp.substring(1, temp.length() - 1);
                        Log.d("getSerialnoNumbers", temp);
                        Message msg = new Message();
                        msg.obj = temp;
                        mHandler.sendMessage(msg);
                        break;
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    private static String getAndroidOsSystemProperties(String key) {
        Method systemProperties_get = null;
        String ret;
        try {
            systemProperties_get = Class.forName("android.os.SystemProperties").getMethod("get",
                    String.class);
            if ((ret = (String) systemProperties_get.invoke(null, key)) != null)
                return ret;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

        return "";
    }

    /**
     * 获取手机IMEI码
     */
    private static String getPhoneIMEI(Context cxt) {

        TelephonyManager tm = (TelephonyManager) cxt.getSystemService(Context.TELEPHONY_SERVICE);
        String deviceId = "";
        try {
            deviceId = tm.getDeviceId();
        } catch (Exception e) {
            e.printStackTrace();
            deviceId = Settings.Secure.getString(cxt.getApplicationContext().getContentResolver(), Settings.Secure.ANDROID_ID);
        }
        return deviceId;
    }

    /**
     * 返回当前程序版本号
     */
    private static String getAppVersionCode(Context context) {
        int versioncode = 0;
        try {
            PackageManager pm = context.getPackageManager();
            PackageInfo pi = pm.getPackageInfo(context.getPackageName(), 0);
            // versionName = pi.versionName;
            versioncode = pi.versionCode;
        } catch (Exception e) {
            Log.d("VersionInfo", "Exception", e);
        }
        return versioncode + "";
    }

    /**
     * 返回当前程序版本名
     */
    private static String getAppVersionName(Context context) {
        String versionName = null;
        try {
            PackageManager pm = context.getPackageManager();
            PackageInfo pi = pm.getPackageInfo(context.getPackageName(), 0);
            versionName = pi.versionName;
        } catch (Exception e) {
            Log.d("VersionInfo", "Exception", e);
        }
        return versionName;
    }
    
}
